package com.uinnova.product.eam.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.MessageException;
import com.binary.framework.exception.ServiceException;
import com.uinnova.product.eam.base.model.DictInfo;
import com.uinnova.product.eam.comm.model.es.AppSquareConfig;
import com.uinnova.product.eam.config.Env;
import com.uinnova.product.eam.model.AppSquareConfigBo;
import com.uinnova.product.eam.model.BusinessConfigResponseVo;
import com.uinnova.product.eam.model.BusinessConfigVo;
import com.uinnova.product.eam.service.AppSquareConfigSvc;
import com.uinnova.product.eam.service.BusinessConfigSvc;
import com.uinnova.product.eam.service.system.IDictSvc;

import com.uino.bean.permission.base.SysModule;
import com.uino.dao.permission.ESModuleSvc;
import com.uino.util.digest.impl.type.Base64Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @description: 功能配置
 * @author: Lc
 * @create: 2022-08-05 18:38
 */
@Slf4j
@Service
public class BusinessConfigSvcImpl implements BusinessConfigSvc {

    private static final String FILE_NAME = "uino_business_config.json";
    private static final String ENCODING = "UTF-8";
    private static final String BUSINESS_MODULE = "BUSINESS_MODULE";

    @Value("${local.resource.space}")
    private String localPath;

    @Resource
    private ESModuleSvc esModuleSvc;

    @Resource
    private IDictSvc dictSvc;

    @Resource
    private AppSquareConfigSvc basicOperationSettingSvc;

    @Override
    public List<BusinessConfigResponseVo> getBusinessConfigList() {
        List<BusinessConfigResponseVo> configList = new ArrayList<>();
        List<DictInfo> dictInfoList = dictSvc.selectListByType(Collections.singletonList(BUSINESS_MODULE), null, Env.DICT.getClassName());
        dictInfoList.forEach(dictInfo -> {
            BusinessConfigResponseVo dict = new BusinessConfigResponseVo();
            BeanUtils.copyProperties(dictInfo, dict);
            dict.setType(1);
            if (Objects.equals(dict.getIsMajor(), "2")) {
                AppSquareConfigBo appSquareConfigBo = new AppSquareConfigBo();
                appSquareConfigBo.setIsInit(0);
                List<AppSquareConfig> listInfo = basicOperationSettingSvc.getListInfo(appSquareConfigBo);
                listInfo.forEach(config -> {
                    BusinessConfigResponseVo configInfo = new BusinessConfigResponseVo();
                    configInfo.setType(2);
                    configInfo.setId(config.getId());
                    configInfo.setCodeName(config.getCardName());
                    configInfo.setParentCode(dict.getCodeCode());
                    configInfo.setIsMajor("0");
                    configList.add(configInfo);
                });
            }
            configList.add(dict);
        });
        return configList;
    }

    @Override
    public ResponseEntity<byte[]> exportConfig(BusinessConfigVo businessConfigVo) {

        // 查询所有二级配置系统模块数据
        List<SysModule> sysModuleList = null;
        if (!CollectionUtils.isEmpty(businessConfigVo.getSysConfigList())) {
            sysModuleList = esModuleSvc.getSysModuleIdList(null, businessConfigVo.getSysConfigList());
        }
        List<Integer> businessGroupList = Stream.of(businessConfigVo.getFixedModule()).collect(Collectors.toList());
        // 查询所有一级配置系统模块数据
        List<SysModule> businessGroupIdList = esModuleSvc.getSysModuleIdList(businessGroupList, null);
        if (!CollectionUtils.isEmpty(sysModuleList) && !CollectionUtil.isEmpty(businessGroupIdList)) {
            sysModuleList.addAll(businessGroupIdList);
        }
        if (CollectionUtils.isEmpty(sysModuleList) && !CollectionUtil.isEmpty(businessGroupIdList)) {
            sysModuleList = new ArrayList<>();
            sysModuleList.addAll(businessGroupIdList);
        }
        Set<Long> allParentModuleId = new HashSet<>();
        if (!CollectionUtils.isEmpty(sysModuleList)) {
            Set<Long> parentModuleId = sysModuleList.stream().map(module -> module.getParentId()).collect(Collectors.toSet());
            // 递归获取父id
            parentModuleId.forEach(moduleId -> {
                handleModule(moduleId, allParentModuleId);
            });
        }
        List<Long> businessModuleIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysModuleList)) {
            businessModuleIdList = sysModuleList.stream().map(SysModule::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(allParentModuleId)) {
                List<Long> parentIdList = new ArrayList<>(allParentModuleId);
                businessModuleIdList.addAll(parentIdList);
            }
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("sysConfig", businessModuleIdList);
        jsonObject.put("squareConfig", businessConfigVo.getSquareConfigList());
        // 内容进行加密操作
        String content = Base64Util.base64(jsonObject.toJSONString());

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(content);
        String result = jsonArray.toJSONString();
        // 导出配置文件
        File file = new File(FILE_NAME);
        FileOutputStream output = null;
        try {
            output = new FileOutputStream(file);
            IOUtils.write(result, output, ENCODING);
        } catch (Exception e) {
            throw new ServiceException("文件生成流异常!");
        } finally {
            try {
                if (output != null) {
                    output.close();
                }
            } catch (Exception e) {
                log.error(String.format("关闭资源异常: %s", e.getMessage()));
            }
        }

        // 返回文件响应格式
        ResponseEntity<byte[]> responseEntity = returnRes(file);
        FileUtils.deleteQuietly(file);
        return responseEntity;
    }

    private void handleModule(Long moduleId, Set<Long> moduleIdSet) {
        SysModule sysModule = esModuleSvc.getById(moduleId);
        if (sysModule != null) {
            moduleIdSet.add(sysModule.getId());
            if (sysModule.getParentId() != null && !Objects.equals(sysModule.getParentId(), 0L)) {
                handleModule(sysModule.getParentId(), moduleIdSet);
            }
        }
    }

    private ResponseEntity<byte[]> returnRes(File file) {
        HttpHeaders headers = new HttpHeaders();
        ResponseEntity<byte[]> entity;
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), ENCODING));
            entity = new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            throw new MessageException(e.getMessage());
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
                log.error(String.format("关闭资源异常: %s", e.getMessage()));
            }
        }
        return entity;
    }

}
